home *** CD-ROM | disk | FTP | other *** search
/ CD World Haziran 1997 / CD World Haziran 1997.iso / Cesitlemeler / Directx 3.0 / dx3.exe / SDK / SAMPLES / DUEL / DS3DUTIL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-09  |  11.2 KB  |  338 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File:       ds3dutil.c
  6.  *  Content:    Routines for dealing with sounds from resources
  7.  *              The last 3 functions (the wave file parsing code)
  8.  *              are copied from dsutil.cpp
  9.  *
  10.  *
  11.  ***************************************************************************/
  12. #include <tchar.h>
  13. #include <dsound.h>
  14. #include "ds3dutil.h"
  15. //*************************** FUNCTION PROTOTYPES **************************/
  16. BOOL DSParseWaveResource(void *pvRes, WAVEFORMATEX **ppWaveHeader,
  17.                          BYTE **ppbWaveData,DWORD *pcbWaveSize);
  18. BOOL DSGetWaveResource ( HMODULE hModule, LPCTSTR lpName,
  19.                          WAVEFORMATEX **ppWaveHeader, BYTE **ppbWaveData,
  20.                          DWORD *pcbWaveSize);
  21. BOOL DSFillSoundBuffer(  IDirectSoundBuffer *pDSB, BYTE *pbWaveData, DWORD cbWaveSize);
  22. BOOL DSReloadSoundBuffer(IDirectSoundBuffer *pDSB, LPCTSTR lpName);
  23.  
  24. //*************************** GLOBAL VARIABLES **************************/
  25.  
  26. _TCHAR gszWaveString[5] = _T("WAVE");
  27.  
  28. /*****************************************************************************
  29. FUNCTION:  WaveInit
  30.  
  31. PURPOSE:   Loads a WAVEDATA struct with the named WAVE resource.
  32.  
  33. PARAMETERS:
  34. lplpWD  A pointer to a WAVEDATA struct.
  35.  
  36. lpDS:   A pointer to an IDirectSound object.  This object must be,
  37.         initialized BEFORE being passed to this function, and MUST have been
  38.         initialized with the DSBCAPS_CTRL3D flag.
  39.  
  40. lpName: A string that contains the name of the .WAV resource.
  41. *****************************************************************************/
  42. BOOL WaveInit(LPWAVEDATA *lplpWD, LPDIRECTSOUND lpDS, LPCTSTR lpName)                   
  43. {
  44. DSBUFFERDESC dsBD = {0};
  45. BYTE *pbWaveData=NULL;
  46. LPWAVEDATA lpWD;
  47.  
  48. lpWD = (*lplpWD) = (LPWAVEDATA)malloc(sizeof(WAVEDATA));
  49. lpWD->lpDirectSoundBuffer = NULL;
  50. lpWD->lpName = NULL;
  51. lpWD->lpDS = NULL;
  52.  
  53. #ifndef UNICODE
  54.     lpWD->lpName = (LPTSTR)malloc(strlen(lpName) + 1);
  55. #else
  56.     lpWD->lpName = (LPTSTR)malloc(2*(wcslen(lpName) + 1));
  57. #endif
  58.     if (lpWD->lpName != NULL)
  59.     {
  60.         _tcscpy(lpWD->lpName, lpName);
  61.         
  62.         if (DSGetWaveResource(NULL, lpName, &dsBD.lpwfxFormat, &pbWaveData, &dsBD.dwBufferBytes))
  63.         {
  64.             dsBD.dwSize = sizeof(DSBUFFERDESC);
  65.             dsBD.dwFlags = DSBCAPS_STATIC     | DSBCAPS_GETCURRENTPOSITION2  | DSBCAPS_CTRL3D;
  66.             if (DS_OK == IDirectSound_CreateSoundBuffer(lpDS, &dsBD, &lpWD->lpDirectSoundBuffer, NULL))
  67.             {
  68.                 if (DSFillSoundBuffer(lpWD->lpDirectSoundBuffer, pbWaveData, dsBD.dwBufferBytes))
  69.                 {
  70.                     lpWD->lpDS = lpDS; //also copy the DirectSoundObject
  71.                     return(TRUE);
  72.                 }
  73.                 IDirectSoundBuffer_Release(lpWD->lpDirectSoundBuffer);
  74.                 lpWD->lpDirectSoundBuffer = NULL;
  75.             }
  76.         }
  77.         free(lpWD->lpName);        
  78.         lpWD->lpName = NULL;
  79.     }
  80.     free(*lplpWD);
  81.     *lplpWD = NULL;
  82.     return(FALSE);
  83. };        
  84.  
  85.  
  86. /*****************************************************************************
  87. FUNCTION:   WaveGetBuffers
  88.  
  89. PARAMS:     lplpWD  A pointer to a WAVEDATA struct.
  90.  
  91.             lplpDirectSoundBuffer:
  92.                 The address of a pointer to a DirectSoundBuffer Interface.                
  93.             lplpDirectSound3DBuffer:
  94.                 The address of a pointer to a DirectSound3DBuffer Interface.
  95.             
  96.             Both of these must be Release()'d after their use.
  97.                 
  98. PURPOSE:    Gives the caller back two interface pointers:  one to a regular
  99.             DirectSoundBuffer interface and one to a 3D buffer interface.  These
  100.             MUST be Released() by the caller.
  101.  
  102. RETURNS:    Should always return TRUE, unless something really catastrophic has happened.
  103.  
  104. NOTES:      BOTH of these Interfaces MUST be ->Release()'d when the object
  105.             or whatever is done using them.  Otherwise the buffer they point
  106.             to will just hang around and waste memory.  This wastes processing time,
  107.             since each buffer is checked by the mixer quite frequently to see if it
  108.             is playing.
  109.  
  110.             Defaults:  Both Position and Velocity vectors are set to (0,0,0).
  111.             
  112. **************************************************************************************/ 
  113. BOOL WaveGetBuffers (LPWAVEDATA lpWD,
  114.                     LPDIRECTSOUNDBUFFER   *lplpDirectSoundBuffer,
  115.                     LPDIRECTSOUND3DBUFFER *lplpDirectSound3DBuffer)
  116. {
  117.     if (DS_OK==IDirectSound_DuplicateSoundBuffer(lpWD->lpDS, lpWD->lpDirectSoundBuffer, lplpDirectSoundBuffer))
  118.     {
  119.         if (DS_OK==IDirectSoundBuffer_QueryInterface(*lplpDirectSoundBuffer, &IID_IDirectSound3DBuffer, (void **)lplpDirectSound3DBuffer))        
  120.         {            
  121.             return TRUE;
  122.         }
  123.     IDirectSoundBuffer_Release(*lplpDirectSoundBuffer);
  124.     *lplpDirectSoundBuffer=NULL;
  125.     *lplpDirectSound3DBuffer = NULL;
  126.     }    
  127.     return FALSE;
  128. };
  129.  
  130.  
  131.  
  132. /*****************************************************************************
  133. FUNCTION:  WaveFree
  134.  
  135. PURPOSE:   When this is called, we HOPE that all the buffers
  136.            (both the normal and the 3D ones) duplicated from "lpDirectSoundBuffer"
  137.            in the function WaveGetBuffers() have been ->Release()'d.  This frees
  138.            up the original buffer (lpDirectSoundBuffer) that all the other buffers
  139.            have been duplicated from.
  140. *****************************************************************************/ 
  141. void WaveFree(LPWAVEDATA lpWD)
  142. {
  143. if (lpWD!=NULL)
  144.     {
  145.     if (lpWD->lpDirectSoundBuffer != NULL)
  146.       IDirectSoundBuffer_Release(lpWD->lpDirectSoundBuffer);
  147.     if (lpWD->lpName != NULL)
  148.         free(lpWD->lpName);
  149.     free(lpWD);
  150.     }
  151. };
  152.  
  153. /*****************************************************************************
  154. FUNCTION:   WaveReload
  155.  
  156. PURPOSE:    This reloads the wave's sound effect.
  157. *****************************************************************************/
  158. BOOL WaveReload(LPWAVEDATA lpWD)
  159. {
  160. return DSReloadSoundBuffer(lpWD->lpDirectSoundBuffer, lpWD->lpName);
  161. };
  162.  
  163.  
  164.  
  165. /*****************************************************************************
  166. FUNCTION:  DSGetWaveResource
  167.  
  168. PURPOSE:   Sets the following:
  169.             a. A pointer to a WAV file header structure
  170.             b. A pointer to the WAV file data.
  171.             c. A DWORD which is the length of the data (in bytes, not samples)
  172. *****************************************************************************/
  173. BOOL DSGetWaveResource(HMODULE hModule, LPCTSTR lpName,
  174.                        WAVEFORMATEX **ppWaveHeader, BYTE **ppbWaveData,
  175.                        DWORD *pcbWaveSize)
  176. {
  177.     HRSRC hResInfo;
  178.     HGLOBAL hResData;
  179.     void *pvRes;
  180.     
  181.  
  182.     if (((hResInfo = FindResource(hModule, lpName, gszWaveString)) != NULL) &&
  183.         ((hResData = LoadResource(hModule, hResInfo)) != NULL) &&
  184.         ((pvRes = LockResource(hResData)) != NULL) &&        
  185.         DSParseWaveResource(pvRes, ppWaveHeader, ppbWaveData, pcbWaveSize))
  186.     {
  187.         return TRUE;
  188.     }
  189.     return FALSE;
  190. }
  191.  
  192.  
  193.  
  194.  
  195. /*****************************************************************************
  196. FUNCTION:   DSParseWaveResource
  197.  
  198. PURPOSE:    This does the real meat of the file parsing, and is called by
  199.             DSGetWaveResource
  200. *****************************************************************************/
  201. BOOL DSParseWaveResource(void *pvRes, WAVEFORMATEX **ppWaveHeader,
  202.                          BYTE **ppbWaveData,DWORD *pcbWaveSize)
  203. {
  204.     DWORD *pdw;
  205.     DWORD *pdwEnd;
  206.     DWORD dwRiff;
  207.     DWORD dwType;
  208.     DWORD dwLength;
  209.  
  210.     if (ppWaveHeader)
  211.         *ppWaveHeader = NULL;
  212.  
  213.     if (ppbWaveData)
  214.         *ppbWaveData = NULL;
  215.  
  216.     if (pcbWaveSize)
  217.         *pcbWaveSize = 0;
  218.  
  219.     pdw = (DWORD *)pvRes;
  220.     dwRiff = *pdw++;
  221.     dwLength = *pdw++;
  222.     dwType = *pdw++;
  223.  
  224.     if (dwRiff != mmioFOURCC('R', 'I', 'F', 'F'))
  225.         goto exit;      // not even RIFF
  226.  
  227.     if (dwType != mmioFOURCC('W', 'A', 'V', 'E'))
  228.         goto exit;      // not a WAV
  229.  
  230.     pdwEnd = (DWORD *)((BYTE *)pdw + dwLength-4);
  231.  
  232.     while (pdw < pdwEnd)
  233.     {
  234.         dwType = *pdw++;
  235.         dwLength = *pdw++;
  236.  
  237.         switch (dwType)
  238.         {
  239.         case mmioFOURCC('f', 'm', 't', ' '):
  240.             if (ppWaveHeader && !*ppWaveHeader)
  241.             {
  242.                 if (dwLength < sizeof(WAVEFORMAT))
  243.                     goto exit;      // not a WAV
  244.  
  245.                 *ppWaveHeader = (WAVEFORMATEX *)pdw;
  246.  
  247.                 if ((!ppbWaveData || *ppbWaveData) &&
  248.                     (!pcbWaveSize || *pcbWaveSize))
  249.                 {
  250.                     return TRUE;
  251.                 }
  252.             }
  253.             break;
  254.  
  255.         case mmioFOURCC('d', 'a', 't', 'a'):
  256.             if ((ppbWaveData && !*ppbWaveData) ||
  257.                 (pcbWaveSize && !*pcbWaveSize))
  258.             {
  259.                 if (ppbWaveData)
  260.                     *ppbWaveData = (LPBYTE)pdw;
  261.  
  262.                 if (pcbWaveSize)
  263.                     *pcbWaveSize = dwLength;
  264.  
  265.                 if (!ppWaveHeader || *ppWaveHeader)
  266.                     return TRUE;
  267.             }
  268.             break;
  269.         }
  270.  
  271.         pdw = (DWORD *)((BYTE *)pdw + ((dwLength+1)&~1));
  272.     }
  273.  
  274. exit:
  275.     return FALSE;
  276. }
  277.  
  278.  
  279.  
  280. /*****************************************************************************
  281. FUNCTION:   DSFillSoundBuffer
  282.  
  283. PURPOSE:    Given an already-initialized DirectSoundBuffer, and pointer to
  284.             some sound data, and the sound data's size, this writes the data
  285.             to the DirectSoundBuffer.
  286. *****************************************************************************/
  287. BOOL DSFillSoundBuffer(IDirectSoundBuffer *pDSB, BYTE *pbWaveData, DWORD cbWaveSize)
  288. {
  289.     if (pDSB && pbWaveData && cbWaveSize)
  290.     {
  291.         LPVOID pMem1, pMem2;
  292.         DWORD dwSize1, dwSize2;
  293.  
  294.         if (SUCCEEDED(IDirectSoundBuffer_Lock(pDSB, 0, cbWaveSize,
  295.             &pMem1, &dwSize1, &pMem2, &dwSize2, 0)))
  296.         {
  297.             ZeroMemory(pMem1, dwSize1);
  298.             CopyMemory(pMem1, pbWaveData, dwSize1);
  299.  
  300.             if ( 0 != dwSize2 )
  301.                 CopyMemory(pMem2, pbWaveData+dwSize1, dwSize2);
  302.  
  303.             IDirectSoundBuffer_Unlock(pDSB, pMem1, dwSize1, pMem2, dwSize2);
  304.             return TRUE;
  305.         }
  306.     }
  307.     return FALSE;
  308. }
  309.  
  310.  
  311. /*****************************************************************************
  312. FUNCTION:   DSReloadSoundBuffer
  313.  
  314. PURPOSE:    If an application with WRITE_PRIMARY takes the focus from our
  315.             humble window, then our secondary sound buffers become "lost" and
  316.             we must call restore and re-fill them.
  317. *****************************************************************************/
  318. BOOL DSReloadSoundBuffer(IDirectSoundBuffer *pDSB, LPCTSTR lpName)
  319. {
  320.     BOOL result=FALSE;
  321.     BYTE *pbWaveData;
  322.     DWORD cbWaveSize;
  323.  
  324.     if (DSGetWaveResource(NULL, lpName, NULL, &pbWaveData, &cbWaveSize))
  325.     {
  326.         if (SUCCEEDED(IDirectSoundBuffer_Restore(pDSB)))
  327.         {
  328.         if (DSFillSoundBuffer(pDSB, pbWaveData, cbWaveSize))
  329.             {
  330.             result = TRUE;
  331.             }
  332.         }
  333.  
  334.     }
  335.  
  336.     return result;
  337. }
  338.